//
// Created by 党清浩 on 2021/10/26.
//
#include  <stdio.h>

#define  TRUE  1
#define  FALSE  0
#define  MAXLEN  50

typedef struct {
    int element[MAXLEN];
    int last;
} Seqlist;// 顺序表用于保存从表达式中提取出的所有整数

typedef struct {
    char ch[MAXLEN];
    int len;
} SString;// 定长顺序串用于保存表达式

typedef struct {
    int flag;
    int number;
} NUM;// 用于保存所提取的一个整数，若提取到数值，则 flag 为 1，且 number 保存该数值，否则 flag 为 0，number 中无数值

// 由字符串 str 生成定长顺序串 S
void StrAsign(SString *S, char *str) {
    int i = 0;
    while (str[i] != '\0') {
        S->ch[i] = str[i];// 填空【1】
        i++; // 填空【2】
    }
    S->len = i;// 填空【3】
}

int InNumber(char ch)// 判断 ch 是否是数值字符
{
    char num[12] = "-0123456789";// 所有的数值字符
    int i = 0;
    while (num[i] != '\0' && ch != num[i])// 在数值字符集中查找是否存在 ch
        i++;
    if (i <= 10)
        return TRUE;    //ch 是数值字符
    else return FALSE;    //ch 不是数值字符
}

NUM GetNumber(SString S,
              int *pos_pointer) {// 从表达式 S 的 * pos_pointer 位置开始，提取出现的第一个数值，比如，若 S 为 “a=123+98*67”，*pos_pointer 为 6，则提取的数值为 98

    NUM t;// 用于保存所提取的数值
    char *q;// 用于循环
    q = S.ch + *pos_pointer - 1;//q 从 S 的指定位置开始
    int i = 0;//i 用于计算偏移量，当数据提取结束后，根据 i 计算下一次提取数据的起始位置
    while (!InNumber(*q) && (i + *pos_pointer <= S.len))// 若 * q 不是数值字符，后移 q
    {
        q++;
        i++;
    }
    if (i + *pos_pointer > S.len)// 若从指定位置循环到表达式结束，说明没遇到数值字符
        t.flag = 0;// 结果变量 t 的 flag 置 0，表示带出的数据中，没有提取到数值
    else  // 遇到了数值字符：-0123456789 之一，即将开始提取数值
    {
        int n = 0, sign = 1;//n 表示所提取的数值，sign 表示所提取数值的符号，默认为正
        if (*q == '-')// 若遇到的数值字符是’-’
        {
            sign = -1;// 说明数值是负数，符号 sign 置 - 1
            q++;//q 移向下一个数值字符，才能再依次提取数值
            i++;
        }
        do// 开始提取数值
        {

            n = n * 10 + *q - '0';// 填空【4】

            q++;// 填空【5】
            i++;
        } while (InNumber(*q) && (i + *pos_pointer <= S.len));// 填空【6】
        t.flag = 1;
        t.number = n * sign;
// 填空【7】
    }
    *pos_pointer += i;// 在 * pos_pointer 基础上，偏移 i，下一次提取数据的起始位置被带出

    return t;// 填空【8】返回所提取数值
}

void get(SString S, Seqlist *L)// 提取表达式 S 中所有的数值，存入顺序表 L
{
    int pos = 1, i = 0;// 起始位置 pos 从 S 的第 1 个字符开始，顺序表接收位置 i 从下标 0 开始
    NUM t;
    while (pos < S.len) {
        t = GetNumber(S, &pos);// 从 S 的 pos 位置起提取第一个数值，结束后的 pos 为下一起始位置，提取结果赋给 t
        if (t.flag == 1) {// 若 t 的标志为 1，说明提取到了数值
            L->element[i] = t.number % 999;// 将该数值转成要求的数值范围，保存
            i++;// 每接收一个数值，i 后移 1
        }
    }
    L->last = i - 1;// 顺序表的 last 置为 i-1
}

void out(Seqlist L)// 输出顺序表 L，即输出提取的所有数值
{
    int i;
    if (L.last == -1)
        printf("Null");
    for (i = 0; i <= L.last; i++)
        printf("%-6d", L.element[i]);
    printf("\n");
}

int main() {
    char exp[MAXLEN];// 保存从键盘输入的表达式字符串

    SString S;// 填空【9】; 定长顺序串 S 保存表达式，串结束不含’\0’
    scanf("%s", exp);// 键盘输入表达式
    Seqlist L;
    // 顺序表 L 置空
    L.last = -1;
    // 填空【10】由字符串 exp 生成 S
    StrAsign(&S, &exp);

    get(S, &L);// 提取表达式 S 中所有数值数据，存入顺序表 L 中
    out(L);// 输出顺序表 L 中所有数值
    return 0;
}
